perm filename MEM[G,BGB]3 blob sn#049881 filedate 1973-06-26 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00006 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	TITLE MEM
C00003 00003	NSUBR MORCOR		Get more core			*
C00005 00004	SUBRS MKNODE,KLNODE	Make and Kill nodes		*
C00007 00005	NSUBR COMPACT
C00012 00006	NSUBR RELOCATE,OFFSET
C00016 ENDMK
C⊗;
TITLE MEM

INTERN OLD44,UNIVER,BLKCNT,AVAIL,INVALID
EXTERN REL
	OLD44:	0	;ORIGINAL JOBREL 44 CONTENTS.
	UNIVER:	0	;POINTER TO UNIVERSE NODE.
	BLKCNT: 0	;NUMBER OF NON EMPTY NODES.
	AVAIL:	0	;POINTER TO FIRST EMPTY NODE.
	REMAINDER:0	;NUMBER OF UNUSED WORDS BETWEEN 
			; THE TOP OF NODE SPACE AND THE TOP OF CORE.
	INVALID:0	;SET DURING SHRINK
	NODSIZ←←=12	;NUMBER OF WORDS PER NODE.
	MINLINK←←-3	;LOWEST NUMBERED LINK
	TYPMASK←←17	;MASK TO EXTRACT TYPE INFORMATION
NSUBR MORCOR		;Get more core			*

;INITIALIZE THE UNIVERSE NODE WHEN NECESSARY.
	SKIPE OLD44↔GO L1		;SKIP ON FIRST TIME ONLY.
	LAC 1,44↔DAC 1,OLD44		;SAVE JOBREL.
	ADDI 1,1↔			;SETUP UNIVERSE NODE.
	ADDI 1,1↔DAC 1,AVAIL
	ADDI 1,1↔DAC 1,BLKCNT
	ADDI 1,1↔DAC 1,UNIVERSE
	SETZM REMAINDER

;FOUR MORE K.
L1:	LAC 1,44↔LAC 0,1↔ADDI 0,10000
	CALLI 11↔FATAL<NO MORE CORE.>
	AOS 1↔SUB 1,REMAINDER↔DAC 2,AC2#↔LAC 2,44
	SETZM(1)↔LIPI(1)↔LAPI(1)1↔BLT(2)
	LACI 2↔DAP @UNIVERSE

;MAKE AVAIL LIST.
	DIP 1,1↔ADD 1,[XWD NODSIZ,0]
	SKIPN@BLKCNT↔GO[
		ADD 1,[XWD NODSIZ,NODSIZ]
		AOS@BLKCNT↔GO .+1]
	DAPZ 1,@AVAIL
L2:	HLRZM 1,(1)↔AOS 3(1)	;EMPTY LINK & EMPTY TYPE-1.
	ADD 1,[XWD NODSIZ,NODSIZ]
	CAILE 2,NODSIZ+NODSIZ-1(1)
	GO L2↔AOS 3(1)

	SUBI 2,NODSIZ-1(1)↔DAC 2,REMAINDER
	LACI 10000↔LAC 1,UNIVER↔ADDM -3(1)	;CORE SIZE.
	LAC 1,@AVAIL
	LAC 2,AC2↔POP0J
SUBREND MORCOR;4-DEC-72(BGB)
;SUBRS MKNODE,KLNODE	;Make and Kill nodes		*
;____________________________________________________________________

NSUBR MKNODE,NODTYP	;ALLOCATE A BLOCK OF NODSIZ WORDS. *
	SKIPN 1,@AVAIL↔CALL MORCOR	;GET AN EMPTY NODE.
	CDR(1)↔DAP @AVAIL
	SETZM(1)↔AOS @BLKCNT↔ADDI 1,3
	POP P,RETADR#			;SAVE RETURN ADDRESS.
	POP P,(1)			;PLACE NODE TYPE INTO NODE.
	GO @RETADR			;RETURN.
SUBREND MKNODE;4-DEC-72(BGB)
;____________________________________________________________________

NSUBR KLNODE,NODE	;RELEASE  BLOCK OF NODSIZ WORDS.
	LAC 1,NODE↔LAC (1)
	CAIN 0,1↔GO [ FATAL(KILLING EMPTY NODE.)]
	SOS @BLKCNT
	LIPI -3(1)↔LAPI -2(1)		;CLEAR NODE.
	SETZM -3(1)↔BLT 8(1)
	AOS(1)				;MARK NODE TYPE EMPTY-1.
	SUBI 1,3↔LAC@AVAIL		;CONS NODE TO AVAIL LIST.
	DAPZ(1)↔DAPZ 1,@AVAIL
	POP1J
SUBREND KLNODE;4-DEC-72(BGB)
NSUBR COMPACT
;Note: to change to handle non-contiguous blocks of node space,
;rewrite the following macro to know about block boundaries.
	DEFINE NXTNOD(AC,LIMIT)
<	ADDI AC,NODSIZ
	CAML AC,LIMIT
>
	ACCUMULATORS{P1,NODE,HOLE,ONE}
;Pass 1: Locate free nodes below BREAK and move nodes in use above
;break into free nodes, leaving pointer in its place to new node
;location.
	MOVE NODE,@BLKCNT	;CALCULATE ADDRESS OF BREAK
	IMULI NODE,NODSIZ
	ADD NODE,UNIVERSE
	MOVEM NODE,BREAK
	SUBI NODE,NODSIZ	;INCREMENTED AT HLOOP
	MOVEI ONE,$EMPTY	;FOR A FAST TYPE CHECK
	SKIPA HOLE,UNIVERSE
HLOOP:	NXTNOD HOLE,BREAK	;FIND A HOLE BELOW BREAK
	GO UPDATE		;BREAK FOUND, NOW UP POINTS
	CAME ONE,(HOLE)		;IS IT AN EMPTY NODE?
	GO HLOOP
NLOOP:	NXTNOD NODE,44		;FIND A NODE ABOVE BREAK
	GO [ WARNING<NODE COUNT TOO BIG>	;HIT TOP END!
	     GO UPDATE ]
	CAMN ONE,(NODE)		;IS IT AN EMPTY NODE?
	GO NLOOP		;NO, TRY NEXT
	HRLZI 0,MINLINK(NODE)	;YES, COPY NODE INTO HOLE BELOW
	HRRI 0,MINLINK(HOLE)
	BLT 0,NODSIZ+MINLINK-1(HOLE)
	HRRZM HOLE,(NODE)	;MAKE POINTER FROM OLD TO NEW LOCATION
	SETOM INVALID
	GO HLOOP
;Pass two: Go thru all of node space and check for pointers between
;BREAK and top of node space and change them to point to new
;location below BREAK.
	PTYPE←HOLE
UPDATE:	SKIPN INVALID
	POPJ P,
	MOVE NODE,UNIVERS
ULOOP:	MOVE PTYPE,(NODE)
	TLNE PTYPE,400400		;FRAME CHEAT
	SETZ PTYPE,
	ANDI PTYPE,TYPMASK
	HLLZ 0,REL(PTYPE)
	LSH 0,6
	MOVEI P1,NODSIZ+MINLINK-1(NODE)
LLOOP:	JUMPE 0,DORIGHT
	JUMPL 0,[HLRZ 1,(P1)
		 CAMGE 1,BREAK
		 GO .+1
		 CAMLE 1,44
		 GO [ WARNING<INVALID POINTER FOUND>
		      GO .+1 ]
		 MOVE 1,(1)
		 HRLM 1,(P1)
		 GO .+1]
	LSH 0,1
	SOJA P1,LLOOP
DORIGH:	HRLZ 0,REL(PTYPE)
	LSH 0,6
	MOVEI P1,NODSIZ+MINLINK-1(NODE)
RLOOP:	JUMPE 0,DONEXT
	JUMPL 0,[HRRZ 1,(P1)
		 CAMGE 1,BREAK
		 GO .+1
		 CAMLE 1,44
		 GO [ WARNING<INVALID POINTER FOUND>
		      GO .+1 ]
		 MOVE 1,(1)
		 HRRM 1,(P1)
		 GO .+1]
	LSH 0,1
	SOJA P1,RLOOP
DONEXT:	NXTNOD NODE,BREAK
	GO .+2
	GO ULOOP
;We're done, now shrink core size and make a new AVAIL list.
;(This may need to be rewritten for non-contiguous node space)
DONE:	MOVE HOLE,BREAK
	MOVEI 0,MINLINK(HOLE)
	CORE 0,
	FATAL<Can't shrink core!>
	HRRZI 1,MINLINK+1(HOLE)
	CAMN 1,44			;CHECK THE OBSCURE CASE
	GO [ SETZB 0,2			;YES, RIGHT ON THE CORE BOUNDARY
	     GO NOFREE ]		;MKNODE WILL GET MORE WHEN IT NEEDS IT
	HRLI 1,MINLINK(HOLE)		;ZERO FREE AREA
	SETZM MINLINK(HOLE)
	MOVE 2,44			;LEAVE TOP IN 2 FOR FAST COMPARES
	BLT 1,(2)
	SETZ 0,
;	SUBI HOLE,NODSIZ
MKLOOP:	CAIGE 2,NODSIZ+MINLINK-1(HOLE)	;IS IT IN CORE?
	GO AVLFIN
	MOVEM ONE,(HOLE)		;SET TYPE BITS
	HRRZM 0,MINLINK(HOLE)		;LINK TO PREVIOUS FREE NODE
	MOVEI 0,MINLINK(HOLE)		;THIS FREE NODE
	ADDI HOLE,NODSIZ
	GO MKLOOP
AVLFIN:	SUBI 2,MINLINK(HOLE)			;AMOUNT OF SPACE LEFT
NOFREE:	MOVEM 2,REMAINDER
	MOVEM 0,@AVAIL
	SETZM INVALID
	MOVE 1,BREAK
	SUB 1,UNIVERSE
	POPJ P,

DECLARE{BREAK}
SUBREND COMPACT;2-MAY-73(TVR)
NSUBR RELOCATE,OFFSET
	DEFINE NXTNOD(AC,LIMIT)
<	ADDI AC,NODSIZ
	CAML AC,LIMIT
>
	ACCUMULATORS{P1,NODE,HOLE,LOWER,UPPER,DELTA}
	PTYPE←←HOLE
	MOVE UPPER,@BLKCNT	;CALCULATE ADDRESS OF BREAK
	IMULI UPPER,NODSIZ
	MOVE NODE,UNIVERS
	MOVEI LOWER,MINLINK(NODE)
	MOVE DELTA,OFFSET
	SUB LOWER,DELTA
	MOVE UPPER,44
	SUB UPPER,DELTA
ULOOP:	MOVE PTYPE,(NODE)
	TLNE PTYPE,400400		;FRAME CHEAT
	SETZ PTYPE,
	ANDI PTYPE,TYPMASK
	HLLZ 0,REL(PTYPE)
	LSH 0,6
	MOVEI P1,NODSIZ+MINLINK-1(NODE)
LLOOP:	JUMPE 0,DORIGHT
	JUMPL 0,[HLRZ 1,(P1)
		 CAML 1,LOWER
		 CAML 1,UPPER
		 GO .+1
		 ADD 1,DELTA
		 HRLM 1,(P1)
		 GO .+1]
	LSH 0,1
	SOJA P1,LLOOP
DORIGH:	HRLZ 0,REL(PTYPE)
	LSH 0,6
	MOVEI P1,NODSIZ+MINLINK-1(NODE)
RLOOP:	JUMPE 0,DONEXT
	JUMPL 0,[HRRZ 1,(P1)
		 CAML 1,LOWER
		 CAML 1,UPPER
		 GO .+1
		 ADD 1,DELTA
		 HRRM 1,(P1)
		 GO .+1]
	LSH 0,1
	SOJA P1,RLOOP
DONEXT:	NXTNOD NODE,44
	GO [ SETZM INVALID↔POP1J ]
	GO ULOOP
SUBREND RELOCATE;2-MAY-73(TVR)